

#ifndef  __ACL_H__
#define  __ACL_H__


#define  RULE_NAME_MAXLEN       (31)
#define  RULE_MAX_PRIORITY      (10000000)
#define  RULE_RESERVED_PRIORITY (0x00000000)
#define  RULE_IGNORE_PRIORITY   (0xfffffffe)
#define  RULE_INVALID_PRIORITY  (0xffffffff)
#define  BITMAP_INVALID_LOC     (0x00000000)
#define  BITMAP_INVALID_VAL     (0x00000000)

typedef enum tagAction
{
    ACTION_DENY,
    ACTION_PERMIT,

    ACTION_MAX
} ACTION_E;

typedef enum tagObject
{
    OBJECT_1,
    OBJECT_2,
    OBJECT_3,
    OBJECT_4,
    OBJECT_5,
    OBJECT_6,
    OBJECT_7,
    OBJECT_8,
    OBJECT_9,
    OBJECT_10,
    OBJECT_11,
    OBJECT_12,
    OBJECT_13,
    OBJECT_14,
    OBJECT_15,

    OBJECT_MAX
} OBJECT_E;

typedef enum tagErrorCode
{
    ERROR_SUCCESS,
    ERROR_INPUT_CHK,
    ERROR_NONE_MEMORY,
    ERROR_CONFLICT,
    ERROR_OVER_SPEC,
    ERROR_NOT_EXIST,
    ERROR_CFG_EXIST,
    ERROR_NOT_MATCH,
    ERROR_OUT_BOUND,

    ERROR_FAILED
} ERROR_CODE_E;

typedef enum tagMoveDir
{
    MOVE_DIR_BEFORE,
    MOVE_DIR_AFTER,

    MOVE_DIR_MAX
} MOVE_DIR_E;


#define  RULE_KEY_NONE          (0X00000000U)
#define  RULE_KEY_BASE          (0X00000001U)
#define  RULE_KEYMASK(type)     (RULE_KEY_BASE << type)

/* Keymask the 1th-8th bit for IP and Service */
#define  RULE_KEY_SIP           (RULE_KEY_BASE)
#define  RULE_KEY_DIP           (RULE_KEY_BASE << 1)
#define  RULE_KEY_SVR           (RULE_KEY_BASE << 2)

/* Keymask the 9th-23th bit for Object */
#define  RULE_KEY_EXT           (8)
#define  RULE_KEY_OBJ_1         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_1))
#define  RULE_KEY_OBJ_2         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_2))
#define  RULE_KEY_OBJ_3         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_3))
#define  RULE_KEY_OBJ_4         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_4))
#define  RULE_KEY_OBJ_5         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_5))
#define  RULE_KEY_OBJ_6         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_6))
#define  RULE_KEY_OBJ_7         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_7))
#define  RULE_KEY_OBJ_8         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_8))
#define  RULE_KEY_OBJ_9         (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_9))
#define  RULE_KEY_OBJ_10        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_10))
#define  RULE_KEY_OBJ_11        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_11))
#define  RULE_KEY_OBJ_12        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_12))
#define  RULE_KEY_OBJ_13        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_13))
#define  RULE_KEY_OBJ_14        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_14))
#define  RULE_KEY_OBJ_15        (RULE_KEY_BASE << (RULE_KEY_EXT+OBJECT_15))

/* Keymask the 24th-32th bit for Reserved */


typedef struct tagPacket
{
    unsigned int   ipSrc;
    unsigned int   ipDest;
    unsigned char  ucL4Pro;
    unsigned short usSrcPort;
    unsigned short usDestPort;
    unsigned int   auiObject[OBJECT_MAX];
} PACKET_S;

typedef struct tagIPv4
{
    unsigned int   uiIp;
} IPV4_S;

typedef struct tagIPv6
{
    unsigned int   auiIp[4];
} IPV6_S;

typedef struct tagPortRange
{
    unsigned short start;
    unsigned short end;
} PORT_RANGE_S;

typedef struct tagService
{
    unsigned char  ucL4Pro;
    PORT_RANGE_S   usSrcPort;
    PORT_RANGE_S   usDestPort;
} SERVICE_S;

typedef struct tagMatchPkt
{
    unsigned int uiKeyMask;
    PACKET_S stPacket;
    unsigned int auiObject[OBJECT_MAX];
} PACKET_INFO_S;

typedef struct tagRuleSummary
{
    char szRuleName[RULE_NAME_MAXLEN+1];
    unsigned int uiPriority;
    ACTION_E enAction;
} RULE_SUMMARY_S;

// rule manage
extern unsigned int RULE_ADD(const char *pcRuleName);
extern unsigned int RULE_DEL(const char *pcRuleName);
extern unsigned int RULE_DEL_ALL();
extern unsigned int RULE_MOVE(const char *pcRuleName, const char *pcTarget, MOVE_DIR_E enDir);
extern unsigned int RULE_PRIORITY(const char *pcRuleName);
extern unsigned int RULE_COUNT();
extern unsigned int RULE_SAVE_CFG(const char *pcCfgName);
extern unsigned int RULE_SAVE_DEFAULT();
extern void RULE_PRINT_CFG();

// rule source ipv4
extern unsigned int RULE_APPEND_SRC_IPV4_RANGE(const char *pcRuleName, unsigned int ipStart, unsigned int ipEnd);
extern unsigned int RULE_REMOVE_SRC_IPV4_RANGE(const char *pcRuleName, unsigned int ipStart, unsigned int ipEnd);
//extern unsigned int RULE_APPEND_SRC_IPV4_WILDCARD(const char *pcRuleName, unsigned int ipBase, unsigned int ipMask);
//extern unsigned int RULE_REMOVE_SRC_IPV4_WILDCARD(const char *pcRuleName, unsigned int ipBase, unsigned int ipMask);
extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_SRC_IPV4(unsigned int uiIPv4);
//extern RULE_SUMMARY_S MATCH_ALL_RULES_BY_SRC_IPV4(unsigned int uiIPv4);

// rule destination ipv4
extern unsigned int RULE_APPEND_DEST_IPV4_RANGE(const char *pcRuleName, unsigned int ipStart, unsigned int ipEnd);
extern unsigned int RULE_REMOVE_DEST_IPV4_RANGE(const char *pcRuleName, unsigned int ipStart, unsigned int ipEnd);
//extern unsigned int RULE_APPEND_DEST_IPV4_WILDCARD(const char *pcRuleName, unsigned int ipBase, unsigned int ipMask);
//extern unsigned int RULE_REMOVE_DEST_IPV4_WILDCARD(const char *pcRuleName, unsigned int ipBase, unsigned int ipMask);
extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_DEST_IPV4(unsigned int uiIPv4);
//extern RULE_SUMMARY_S MATCH_ALL_RULES_BY_DEST_IPV4(unsigned int uiIPv4);

// rule source ipv6
//extern unsigned int RULE_APPEND_SRC_IPV6_RANGE(const char *pcRuleName, IPV6_S ipv6Start, IPV6_S ipv6End);
//extern unsigned int RULE_REMOVE_SRC_IPV6_RANGE(const char *pcRuleName, IPV6_S ipv6Start, IPV6_S ipv6End);
//extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_SRC_IPV6(IPV6_S stIPv6);
//extern RULE_SUMMARY_S MATCH_ALL_RULES_BY_SRC_IPV6(IPV6_S stIPv6);

// rule destination ipv6
//extern unsigned int RULE_APPEND_DEST_IPV6_RANGE(const char *pcRuleName, IPV6_S ipv6Start, IPV6_S ipv6End);
//extern unsigned int RULE_REMOVE_DEST_IPV6_RANGE(const char *pcRuleName, IPV6_S ipv6Start, IPV6_S ipv6End);
//extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_DEST_IPV6(IPV6_S stIPv6);
//extern RULE_SUMMARY_S MATCH_ALL_RULES_BY_DEST_IPV6(IPV6_S stIPv6);

// rule service
//extern unsigned int RULE_APPEND_SERVICE(const char *pcRuleName, SERVICE_S stService);
//extern unsigned int RULE_REMOVE_SERVICE(const char *pcRuleName, SERVICE_S stService);
//extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_SERVICE(SERVICE_S stService);
//extern RULE_SUMMARY_S MATCH_ALL_RULES_BY_SERVICE(SERVICE_S stService);

/*
// rule object
extern unsigned int RULE_APPEND_OBJ(const char *pcRuleName, OBJECT_E enObject, unsigned int uiObj);
extern unsigned int RULE_REMOVE_OBJ(const char *pcRuleName, OBJECT_E enObject, unsigned int uiObj);
extern RULE_SUMMARY_S MATCH_FIRST_RULE_BY_OBJ(OBJECT_E enObject, unsigned int uiObj);

// FORMAL API
extern RULE_SUMMARY_S QUICK_MATCH_IPV4(PACKET_INFO_S stMatchInfo);

// VALGRIND STUB
extern bool __VALGRIND_FLAG__;
static __always_inline void SET_VALGRIND_DEBUG(unsigned int value) { __VALGRIND_FLAG__ = value; }
*/

// rule match
extern unsigned int SWIFT_BUILD();
extern void SWIFT_DESTROY();

extern RULE_SUMMARY_S SWIFT_MATCH_SRC_IPV4(unsigned int uiIPv4);
extern RULE_SUMMARY_S SWIFT_MATCH_DEST_IPV4(unsigned int uiIPv4);

#endif

